<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .father{
      position: relative;
      width: 100px;
      height: 100px;
      margin: 100px auto;
      overflow: hidden;
    }
    .son{
      position: absolute;
      top: -50%;
      left: -50%;
      width: 100px;
      height: 100px;
      border-radius: 50%;
      background-color: aqua;
    }
  </style>
</head>
<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    // 只有函数才能调用，因为给函数的原型上添加的方法，不用方法调用会报错
    Function.prototype._call = function (context) {
      // 判断调用者是否为函数，this就是调用者
      if(typeof this != 'function') {
        return
      }
      // 如果传入了context就指向context，否则指向window
      context = context || window
      // 把调用的函数保存下来,这里就实现了将this转变成context了
      context.fn = this
      // 得到fn里面的参数
      const arg = [...arguments].slice(1)
      let result = context.fn(...arg)
      // 删除传入对象中添加的fn函数
      delete context.fn
      return result
    }
    function foo(a,b,c) {
      console.log(a,b,c);
      console.log(this.a)
      return 2
    }
    let obj = {
      a:21
    }
    foo._call(obj,[23,21,32])
    console.log(obj);
    // foo.call(obj,1,2,3)
  </script>
</body>
</html>